package com.glenet.salary.util;

import java.io.Reader;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

@SuppressWarnings("unchecked")
public class SessionFactoryUtil {

	 /**
     * Parameter used to define the XML Hibernate configuration file
     */
    private static final String IBATIS_CONFIGURATION_FILE_PROPERTY = "ibatis.cfg.xml";
    
    /**
     * Class logger
     */
    private static Log log = LogFactory.getLog(SessionFactoryUtil.class);

    /**
     * The one and only session manager instance
     */
    private static SessionFactoryUtil sessionFactoryUtil = new SessionFactoryUtil();
    /**
     * The one and only Hibernate session factory.
     */
    private static final SqlSessionFactory sessionFactory;

    static {
        try {
            // Create the SessionFactory
        	Reader reader = Resources.getResourceAsReader(IBATIS_CONFIGURATION_FILE_PROPERTY);
        	sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception ex) {
            throw new RuntimeException("Configuration problem: " + ex.getMessage(), ex);
        }
    }
    
    /** 
     * The thread-local Hibernate session object
     */
	private static final ThreadLocal threadSession = new ThreadLocal();
    
    public static SqlSession getSession() throws Exception {
    	return currentSession();
    }
    
    public static SqlSession currentSession() throws Exception {
    	log.debug("Hibernate Session Manager :Fetching a hibernate session");
    	SqlSession s = (SqlSession) threadSession.get();
        // Open a new Session, if this Thread has none yet
        if (s == null) {
            s = sessionFactory.openSession();
            threadSession.set(s);
        }
    	log.debug("Hibernate Session Manager :Fetching a hibernate session done.");
        return s;
    }

    /**
     * Close the current Hibernate session
     * @throws HibernateException
     * @throws InfrastructureException
     */
    public static void closeSession(){
        log.debug("Hibernate Session Manager : closeSession");
        SqlSession s = (SqlSession) threadSession.get();
        threadSession.set(null);
        if (s != null) {
            log.debug("Hibernate Session Manager : closing session");
            s.close();
            log.debug("Hibernate Session Manager : session closed");
        }
        s = null;
    }

    /**
     * Default constructor
     */
    private SessionFactoryUtil() {
        super();
    }
    
    public static SqlSessionFactory getSessionFactory(){
    	return sessionFactory;
    }

    /**
     * Returns an instance of a session mananger used to obtain
     * a Hibernate Session object.
     * @return the Hibernate session manager.
     */
    public static SessionFactoryUtil getInstance() {
        return sessionFactoryUtil;
    }

    public static SqlSession openSession() throws Exception {
        return SessionFactoryUtil.currentSession();
    }
    
    // -- test -- //
    
    public static void main(String[] args) throws Exception {
//		for (int i = 0; i < 10; i++) {
//			System.out.println(SessionFactoryUtil.getInstance().getSession());
//		}
    	System.out.println("sdfasdf");
	}
}
